﻿using System;
using System.Configuration;
using Less.Core.Model;
using Less.Tools;

namespace Less.Core.Loggers
{
    /// <summary>
    /// Logger that sends messages by email
    /// </summary>
    public class MailLogger : BaseLogger
    {
        private string _subject;

        /// <summary>
        /// Constructor
        /// </summary>
        public MailLogger()
        {
            // Only entries with Error or more severiry can use this logger by default
            MinSeverity = EntrySeverities.Error;
        }


        public static string LogMailDestination
        {
            get
            {
                string name = ConfigurationManager.AppSettings["MailLogger.LogMailDestination"];
                if (name == null) name = @"developer@hotmail.com";
                return name;
            }
        }
        /// <summary>
        /// Cero based retries when log fails writing
        /// </summary>
        /// <returns></returns>
        public static int MaxAttempts
        {
            get
            {
                string name = ConfigurationManager.AppSettings["FileLogger.MaxAttempts"];
                if (name == null) name = "1";
                int number = 1024;
                int.TryParse(name, out number);
                return number;
            }
        }


        /// <summary>
        /// Basic writer method. 
        /// <remarks> Will retry whe writing whe fails</remarks>
        /// </summary>
        /// <param name="entrySeverity"></param>
        /// <param name="entryMessage"></param>
        /// <param name="entryCategory"></param>
        /// <param name="entrySource"></param>
        /// <param name="userName"></param>
        /// <param name="processId"></param>
        /// <param name="metricName"></param>
        /// <param name="metricValue"></param>
        /// <returns></returns>
        public override bool Write(EntrySeverities entrySeverity, string entryMessage, EntryCategories entryCategory = EntryCategories.Base, string entrySource = "", string userName = "", long processId = 0, string metricName = "", object metricValue = null)
        {
            string message = ComposeMessage(entrySeverity, entryMessage, entryCategory, entrySource, userName, processId, metricName, metricValue);
            int attempts = 0;
            do
            {
                attempts++;
                try
                {
                    WriteMessage(message);
                    return true;
                }
                catch (Exception e)
                {
                    Log.Error(e, EntryCategories.Log);
                }
            } while (attempts < MaxAttempts);
            return false;
        }

        /// <summary>
        /// Composes the subject a the body of the email generated for this entry
        /// </summary>
        /// <param name="entrySeverity"></param>
        /// <param name="entryMessage"></param>
        /// <param name="entryCategory"></param>
        /// <param name="entrySource"></param>
        /// <param name="userName"></param>
        /// <param name="processId"></param>
        /// <param name="metricName"></param>
        /// <param name="metricValue"></param>
        /// <returns></returns>
        public override string ComposeMessage(EntrySeverities entrySeverity, string entryMessage, EntryCategories entryCategory, string entrySource = "", string userName = "", long processId = 0, string metricName = "", object metricValue = null)
        {
            var logEntry = LogEntry.CreateLogEntry(entrySeverity, entryMessage, entryCategory, entrySource, userName, processId, metricName, metricValue);
            this._subject = string.Format("{0} {1} ", FormatSeverity(logEntry.Severity), FormatCategory(logEntry.Category));
            string newLine = Environment.NewLine + " - ";
            // Format YAML message
            string template = string.Format("{0}: from {1} at {2} {3}  --{4} {5}  --{6} {7} --{8}",
                                            FormatSeverity(logEntry.Severity),
                                            FormatCategory(logEntry.Category),
                                            FormatTimeStamp(logEntry.Created),
                                            newLine,
                                            logEntry.Message,
                                            newLine,
                                            logEntry.Source,
                                            newLine,
                                            logEntry.SystemData);
            return template;
        }

        /// <summary>
        /// Sends the message by email
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public override bool WriteMessage(string message)
        {
            Functions.SendEmailMessage(this._subject, message, LogMailDestination, LogMailDestination);
            return true;
        }
    }
}
